﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DBLibrary;
using System.Xml;

public static class CustomerExtendFieldHelper
{
    private static readonly int mExtFieldsNum = 6;

    private static XmlElement CreateRootXml(XmlDocument doc)
    {
        XmlElement rootEl = doc.CreateElement("Extends");
        rootEl.SetAttribute("maxRow", "0");
        return rootEl;
    }

    private static int GetRootMaxRow(XmlElement rootEl)
    {
        return int.Parse(rootEl.Attributes["maxRow"].Value);
    }

    private static void SetRootMaxRow(ref XmlElement rootEl, int row)
    {
        rootEl.SetAttribute("maxRow", row.ToString());
    }

    private static XmlElement CreateExtendXml(XmlDocument doc, int row, string extField, string extName)
    {
        XmlElement newEl = doc.CreateElement("ExtNode");
        newEl.SetAttribute("row", row.ToString());
        newEl.SetAttribute("extField", extField);
        newEl.SetAttribute("extName", extName);
        return newEl;
    }

    private static int GetNodeRowId(XmlElement el)
    {
        return int.Parse(el.GetAttribute("row"));
    }
    private static void SetNodeRowId(ref XmlElement el, int rowid)
    {
        el.SetAttribute("row", rowid.ToString());
    }

    private static void FindNextAvaliableRowIdAndExtFieldAndUpdateExtendField(XmlElement rootEl, int kvRow, string kvExtField, out int row,out string extField, out bool isNewRowId)
    {
        if (kvRow >= 0 && !string.IsNullOrEmpty(kvExtField))
        {
            row = kvRow;
            isNewRowId = false;
            extField = kvExtField;
        }
        else
        {
            row = GetRootMaxRow(rootEl);
            isNewRowId = false;
            extField = "str1";
            if (rootEl.ChildNodes.Count > 0)
            {
                int count = 0;
                foreach (XmlElement el in rootEl.ChildNodes)
                {
                    if (row == GetNodeRowId(el))
                    {
                        ++count;
                    }
                }
                if (count == mExtFieldsNum)
                {
                    ++row;
                    isNewRowId = true;
                    SetRootMaxRow(ref rootEl, row);
                    extField = "str1";
                }
                else
                {
                    count++;
                    extField = "str" + count;
                }
            }
            else
            {
                isNewRowId = true;
            }
        }
    }

    private static void SetCEDValueAndUpdateXml(XmlDocument doc, ref XmlElement rootEl, ref CustomerExtendDetail ced, int row, string extField, string extValue, string extName, bool isNewField)
    {
        if (isNewField)
        {
            XmlElement el = CreateExtendXml(doc, row, extField, extName);
            rootEl.AppendChild(el);
        }

        if (extField.Equals("str1", StringComparison.OrdinalIgnoreCase))
        {
            ced.StringExt1 = extValue;
        }
        else if (extField.Equals("str2", StringComparison.OrdinalIgnoreCase))
        {
            ced.StringExt2 = extValue;
        }
        else if (extField.Equals("str3", StringComparison.OrdinalIgnoreCase))
        {
            ced.StringExt3 = extValue;
        }
        else if (extField.Equals("str4", StringComparison.OrdinalIgnoreCase))
        {
            ced.StringExt4 = extValue;
        }
        else if (extField.Equals("str5", StringComparison.OrdinalIgnoreCase))
        {
            ced.StringExt5 = extValue;
        }
        else if (extField.Equals("str6", StringComparison.OrdinalIgnoreCase))
        {
            ced.StringExt6 = extValue;
        }
    }

    public static void UpdateOrInsertCustomerDetailInfos(long customerId, List<CustomerExtendKeyValue> list)
    {
        DB db = PoseidonDBHelper.UserDB;
        CustomerDetail cd = db.Select<CustomerDetail>(new DBParam("CustomerId", customerId))[0];
        XmlDocument doc = new XmlDocument();
        XmlElement rootEl = null;
        if (!string.IsNullOrEmpty(cd.Extend))
        {
            doc.LoadXml(cd.Extend);
            rootEl = doc.DocumentElement;
        }
        else
        {
            rootEl = CreateRootXml(doc);
        }
        Dictionary<int, CEDExt> dic = new Dictionary<int, CEDExt>();
        foreach (CustomerExtendKeyValue kv in list)
        {
            bool isNewField = kv.Row < 0 || string.IsNullOrEmpty(kv.ExtField);
            int row;
            bool isNewRow;
            string extField;
            FindNextAvaliableRowIdAndExtFieldAndUpdateExtendField(rootEl, kv.Row, kv.ExtField, out row, out extField, out isNewRow);
            if (isNewRow)
            {
                dic[row] = new CEDExt(true);
                dic[row].CED = new CustomerExtendDetail();
                dic[row].CED.CustomerId = customerId;
                dic[row].CED.Row = row;
                isNewField = true;
            }
            else
            {
                if (!dic.ContainsKey(row))
                {
                    dic[row] = new CEDExt(false);
                    dic[row].CED = db.Select<CustomerExtendDetail>(new DBParam("CustomerId", customerId), new DBParam("Row", kv.Row))[0];
                }
            }
            SetCEDValueAndUpdateXml(doc, ref rootEl, ref dic[row].CED, row, extField, kv.ExtValue, kv.ExtName, isNewField);
        }
        cd.Extend = rootEl.OuterXml;
        foreach (KeyValuePair<int, CEDExt> pair in dic)
        {
            if (pair.Value.IsNew)
            {
                db.Insert(pair.Value.CED);
            }
            else
            {
                db.Update(pair.Value.CED, "CustomerId", "Row");
            }
        }
        db.Update(cd, "CustomerId");
    }

    public static List<CustomerExtendKeyValue> GetCustomerDetailInfos(long customerId)
    {
        List<CustomerExtendKeyValue> list = new List<CustomerExtendKeyValue>();
        DB db = PoseidonDBHelper.UserDB;
        CustomerDetail cd = db.Select<CustomerDetail>(new DBParam("CustomerId", customerId))[0];
        if (!string.IsNullOrEmpty(cd.Extend))
        {
            Dictionary<int, CustomerExtendDetail> cache = new Dictionary<int, CustomerExtendDetail>();
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(cd.Extend);
            foreach (XmlElement el in doc.DocumentElement.ChildNodes)
            {
                int row = int.Parse(el.GetAttribute("row"));
                string field = el.GetAttribute("extField");
                string name = el.GetAttribute("extName");
                if (!cache.ContainsKey(row))
                {
                    CustomerExtendDetail c = db.Select<CustomerExtendDetail>(new DBParam("CustomerId", customerId), new DBParam("Row", row))[0];
                    cache[row] = c;
                }
                CustomerExtendDetail ced = cache[row];
                CustomerExtendKeyValue kv = new CustomerExtendKeyValue();
                kv.ExtName = name;
                kv.Row = row;
                kv.ExtField = field;
                #region 获取扩展字段值与类型
                if (field.Equals("str1", StringComparison.OrdinalIgnoreCase))
                {
                    kv.ExtValue = ced.StringExt1;
                }
                else if (field.Equals("str2", StringComparison.OrdinalIgnoreCase))
                {
                    kv.ExtValue = ced.StringExt2;
                }
                else if (field.Equals("str3", StringComparison.OrdinalIgnoreCase))
                {
                    kv.ExtValue = ced.StringExt3;
                }
                else if (field.Equals("str4", StringComparison.OrdinalIgnoreCase))
                {
                    kv.ExtValue = ced.StringExt4;
                }
                else if (field.Equals("str5", StringComparison.OrdinalIgnoreCase))
                {
                    kv.ExtValue = ced.StringExt5;
                }
                else if (field.Equals("str6", StringComparison.OrdinalIgnoreCase))
                {
                    kv.ExtValue = ced.StringExt6;
                }
                else
                {
                    throw new Exception("GetCustomerDetailInfos error : " + field);
                } 
                #endregion
                list.Add(kv);
            }
        }
        return list;
    }
}

class CEDExt
{
    public CustomerExtendDetail CED;
    private bool mIsNew;
    public bool IsNew { get { return mIsNew; } }
    public CEDExt(bool isNew)
    {
        mIsNew = isNew;
    }
}